﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Text;

namespace Workers
{
    public class Joiner : Worker
    {
        private string m_startingFile;

        private string m_destinationPath;

        public void Run(string startingFile, string destinationPath)
        {
            m_startingFile = startingFile;
            m_destinationPath = destinationPath;
         
            m_backgroundWorker.DoWork += new DoWorkEventHandler(Joiner_DoWork);
            m_backgroundWorker.RunWorkerAsync();
        }

        private void Joiner_DoWork(object sender, DoWorkEventArgs e)
        {
            string startingFileName = Path.GetFileName(m_startingFile);
            string startingFilePath = Path.GetDirectoryName(m_startingFile);
            string outputFileName = startingFileName.Substring(0, startingFileName.LastIndexOf("."));

            int totalSplitFiles = 1;
            string fileToProcess = startingFilePath + Path.DirectorySeparatorChar + outputFileName + "." + totalSplitFiles;
            while (File.Exists(fileToProcess))
            {
                totalSplitFiles += 1;
                fileToProcess =
                    startingFilePath + Path.DirectorySeparatorChar + outputFileName + "." + totalSplitFiles;
            }

            int counter = 1;
            fileToProcess = startingFilePath + Path.DirectorySeparatorChar + outputFileName + "." + counter;

            using (FileStream writeFs = new FileStream(
                m_destinationPath + Path.DirectorySeparatorChar + outputFileName, FileMode.Create))
            {
                using (BinaryWriter bw = new BinaryWriter(writeFs))
                {
                    while (File.Exists(fileToProcess))
                    {
                        if ((sender as BackgroundWorker).CancellationPending)
                        {
                            e.Cancel = true;
                            return;
                        }

                        FileStream fs = new FileStream(fileToProcess, FileMode.Open, FileAccess.Read);
                        using (BinaryReader br = new BinaryReader(fs))
                        {
                            while (br.BaseStream.Position != br.BaseStream.Length)
                            {
                                // joining in arbitrary 1 MB increments
                                bw.Write(br.ReadBytes(1024 * 1024));
                            }
                        }

                        counter += 1;
                        fileToProcess = 
                            startingFilePath + Path.DirectorySeparatorChar + outputFileName + "." + counter;

                        (sender as BackgroundWorker).ReportProgress((int)(((float)counter / (float)totalSplitFiles) * 100));
                    }
                }
            }
        }
    }
}
